﻿using System.Collections.ObjectModel;
using System.Linq;

namespace LightCAD.Core
{
    public abstract class LcComponentDefinition : LcObject
    {
        public string Uuid { get; set; }
        public string Name { get; set; }//例如：SingleDoor45
        public string DisplayName { get; set; }//例如：单扇平开门_半开
        public string Category { get; set; }//例如：Door
        public string SubCategory { get; set; }//例如：SwingDoor
        public string Description { get; set; }
        public string Namespace { get; set; }
        public string Major { get; set; }
        public string UseType { get; set; }
        public Vector3 Origin { get; set; }=new Vector3();
        #region 内置    如果是机械设备之类的没有内置 只有Lib
        public ParameterSetDefinition Parameters { get; set; }
        /// <summary>
        /// 如果加载的时候没有取到这个Curve2dProvider  就直接用投影轮廓
        /// </summary>
        public Curve2dProvider Curve2dProvider { get; set; }
        public Solid3dProvider Solid3dProvider { get; set; }
        #endregion


        public ParameterSetDefinition LibParameters { get; set; }
        public Curve2dProvider LibCurve2dProvider { get; set; }
        public Solid3dProvider LibSolid3dProvider { get; set; }

        /// <summary>
        /// 类型参数 一个组件下所有实例共享的参数 比如材质 同一个组件类管理的不同组件，类型参数可以不一样，但是该组件的所有实例共享其类型参数
        /// </summary>
        public LcParameterSet TypeParameters { get; set; }
        public LcComponentDefinition() 
        {
        }
        public LcComponentDefinition(string uuid, string name,string category,string subcategory, LcParameterSet typeParams) 
        {
            this.Uuid=uuid;
            this.Name = name;
            this.Category = category;
            this.SubCategory= subcategory;
            this.TypeParameters = typeParams;
        }

        public virtual void WriteProperties(Utf8JsonWriter writer, JsonSerializerOptions soptions)
        {
            writer.WriteStringProperty("TypeName", this.GetType().Name);
            writer.WriteStringProperty(nameof(this.Uuid), this.Uuid);
            writer.WriteStringProperty(nameof(this.Name), this.Name);
            writer.WriteStringProperty(nameof(this.Category), this.Category);
            writer.WriteStringProperty(nameof(this.SubCategory), this.SubCategory);

            writer.WriteCollectionProperty("TypeParameterValues", this.TypeParameters.Values, soptions, (w, val) => JsonSerializer.Serialize(writer, val, soptions));
        }

        public virtual void ReadProperties(ref JsonElement jele)
        {
            this.Uuid = jele.ReadStringProperty(nameof(this.Uuid));
            this.Name = jele.ReadStringProperty(nameof(this.Name));
            this.Category = jele.ReadStringProperty(nameof(this.Category));
            this.SubCategory = jele.ReadStringProperty(nameof(this.SubCategory));

            var exist = jele.TryGetProperty("TypeParameterValues", out JsonElement prop);
            if (exist && !prop.NullOrUndefined())
            {
                var arr = prop.EnumerateArray().ToArray();
                for (var i = 0; i < arr.Length; i++)
                {
                    var item = arr[i];
                    object obj = JsonSerializer.Deserialize<object>(item);
                    if (item.ValueKind == JsonValueKind.String)
                    {
                        obj = obj.ToString();
                    }
                    this.TypeParameters.SetValue(i, obj);
                }
            }
        }

    }
    public class ComponentCollection : KeyedCollection<string, LcComponentDefinition>
    {
        protected override string GetKeyForItem(LcComponentDefinition item)
        {
            return item.Uuid;
        }

        public LcComponentDefinition Find(string category, string name)
        {
            return this.FirstOrDefault(item => item.Category == category && item.Name == name);
        }
    }







}